`
https://leetcode.cn/problems/swim-in-rising-water/
`

// 该解法无法通过所有测试用例，存在超时问题，仅作为思路参考

/**
 * @param {number[][]} grid
 * @return {number}
 */
var swimInWater = function (grid) {
  const n = grid.length
  const used = createMultiDimArray(n, n, () => false)
  const memo = new Map()
  const direc = [[1, 0], [-1, 0], [0, 1], [0, -1]]
  // dp(i, j, wait) 表示从 (0, 0) 到 (i, j) 至少要等待 wait 秒
  const dp = (i, j, wait) => {
    if (i < 0 || i >= n || j < 0 || j >= n || used[i][j]) return Infinity
    if (memo.has(`${i}-${j}-${wait}`)) return memo.get(`${i}-${j}-${wait}`)
    if (i === n - 1 && j === n - 1) return Math.max(wait, grid[i][j])

    let res = Infinity
    const nextWait = Math.max(wait, grid[i][j])

    used[i][j] = true
    for (const [x, y] of direc) {
      res = Math.min(res, dp(i + x, j + y, nextWait))
    }
    used[i][j] = false
    memo.set(`${i}-${j}-${wait}`, res)
    return res
  }
  return dp(0, 0, grid[0][0])
};

function createMultiDimArray(...args) {
  if (args.length === 0) return [];
  if (args.length === 1) {
    if (typeof args[0] === 'function') return [args[0]()];
    return new Array(args[0]).fill(undefined)
  };
  if (args.length === 2) {
    if (typeof args[1] === 'function') return Array.from({ length: args[0] }, () => args[1]());
    return new Array(args[0]).fill(args[1]);
  }
  return Array.from({ length: args[0] }, () => createMultiDimArray(...args.slice(1)));
}